---
id: lab-ansible-intro
slug: /labs/ansible
sidebar_position: 1
---

# Ansible, Playbook

## Подготовка к работе

- Работа в операционной системе семейства Linux;
- Уставленные Docker, Docker Compose;
- Установленный пакет Python3.

## Отчет

Отчет в формате `docx`. Обязательное содержимое отчета:

- Фамилия и инициалы студента, номер группы, номер варианта;
- План и задачи лабораторной работы;
- Краткое описание хода выполнения работы;
- Скриншоты результатов заданий и ответы на вопросы задания.

### Дополнительные материалы

Для выполнения лабораторной работы необходимы будут материалы лекций:

- [Docker](./../../lectures/docker/intro.md);
- [Docker Compose](./../../lectures/docker/intro.md);
- [Ansible](./../../lectures/ansible/intro.md).

### Подготовка проекта

- Скачать проект [DevOps](https://hub.mos.ru/iu5bmstu/lections-and-labs/devops/textbook) на локальную машину:

  ![download.png](./images/download.png)

- Разархивировать проект и зайти в папку с проектом:

  ```bash
  cd src/labs/ansible
  ```

  ```bash
  Структура директории
  ├── ansible
  │   ├── ansible.cfg
  │   ├── Dockerfile
  │   ├── inventory
  │   │   ├── all_vars
  │   │   ├── ansible_master_vars
  │   │   ├── application_vars
  │   │   ├── database_vars
  │   │   └── workers
  │   └── playbooks
  │       ├── app
  │       │   ├── app.py
  │       │   ├── env.j2
  │       │   └── requirements.txt
  │       ├── mysql
  │       │   ├── dump.sql
  │       │   ├── permissions.sql
  │       │   └── root_cnf.j2
  │       ├── nginx
  │       │   └── nginx.conf.j2
  │       ├── playbook-application.yml
  │       └── playbook-database.yml
  ├── docker-compose.yml
  ├── lab6-agent
  │   ├── build.sh
  │   └── Dockerfile
  └── README.MD
  ```

Работу можно выполнять:

- на виртуальной машине (тогда с помощью `scp` скопируйте папку из хостовой машины в виртуальную машину или выполните клонирование репозитория методички в виртуальную машину);
- в хостовой операционной системе через [Docker Desktop](https://www.docker.com/products/docker-desktop/).

### Установка lab6-agent и проверка тестового стенда

```bash
cd  lab6-agent

# собираем образ базового контейнера для лабы
./build.sh
```

Поднимаем тестовый стенд:

```bash
cd ../
docker-compose up -d
```

После успешной компиляции образов и старта кластера:

```bash
docker-compose down
```

## Задачи лабораторной работы

### Задание 1: Поднять кластер и установить тестовую базу данных

Поднимаем тестовый стенд:

```bash
docker-compose up -d --scale app=3
```

О том, как работает горизонтальное масштабирование в Docker Compose, можно почитать [здесь](https://karthi-net.medium.com/how-to-scale-services-using-docker-compose-31d7b83a6648). Делаем листинг запущенных контейнеров:

```bash
docker ps
```

![dockerps.png](./images/dockerps.png)

Находим контейнер `ansible-ansible-1` или `ansible_ansible_1` (в разных реализациях docker-compose бывает по разному).

:::caution
Важно! Необходимо заменить в [инвентори файле](https://hub.mos.ru/iu5bmstu/lections-and-labs/devops/textbook/-/blob/main/src/labs/ansible/ansible/inventory/workers) на `_` или `-` в зависимости от названия в системе.
:::

Заходим на хост с ансиблем:

```bash
docker exec -it `docker ps -aqf "name=ansible-ansible-1"` bash
# или
docker exec -it `docker ps -aqf "name=ansible_ansible_1"` bash
```

#### Ad-hoc команды

**Ad-hoc** - вызов отдельных команд.

`ping` - проверяем доступность хостов инвернтори:

```bash
ansible all -m ping
```

Пример вывода:

```bash
ansible-app-2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
ansible-app-3 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
ansible-app-1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
```

Команда `uptime` - проверяем сколько времени поднят сервер:

```bash
ansible all -m command -a 'uptime'
```

Пример вывода:

```bash
ansible-app-2 | CHANGED | rc=0 >>
19:08:47 up 1 day,  4:18,  1 user,  load average: 1.39, 1.14, 1.22
ansible-app-1 | CHANGED | rc=0 >>
19:08:47 up 1 day,  4:18,  1 user,  load average: 1.39, 1.14, 1.22
ansible-app-3 | CHANGED | rc=0 >>
19:08:47 up 1 day,  4:18,  1 user,  load average: 1.39, 1.14, 1.22
```

Запускаем [плейбук для установки базы](https://hub.mos.ru/iu5bmstu/lections-and-labs/devops/textbook/-/blob/main/src/labs/ansible/ansible/playbooks/playbook-database.yml):

```bash
ansible-playbook /playbooks/playbook-database.yml
```

Плейбук поставит и установит базу на хост `ansible_app_3`.

Проверяем заходим на хост с базой (из масер-хоста `ansible: ansible_ansible_1`):

```bash
ssh ansible_app_3
```

На хосте заходим в клиент базы `mysql`:

```bash
mysql
```

выбираем созданную базу `testdb`:

```bash
mysql> use testdb
```

Пример вывода:

```bash
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
```

Сделаем `SELECT` из тестовой таблицы

```bash
mysql> select * from test;
```

Пример вывода

```bash
+--------------------+
| message            |
+--------------------+
| Ansible To Do List |
| Get ready          |
| Ansible is fun     |
+--------------------+
3 rows in set (0.00 sec)

```

### Задание 2: Подготовить работу приложений

Запускаем [плейбук для установки приложений](https://hub.mos.ru/iu5bmstu/lections-and-labs/devops/textbook/-/blob/main/src/labs/ansible/ansible/playbooks/playbook-application.yml):

```bash
ansible-playbook /playbooks/playbook-application.yml
```

Проверим что процесс работает на хосте:

```bash
ssh ansible_app_1
```

После логина найдем что процесс запущен:

```bash
ps ax | grep python
```

И убедимся что порт `5000` открыт:

```bash
netstat -nlp | grep 5000
```

Для проверки, что приложение запущено на всех хостах и чтобы не проверять по одному, воспользуемся adhoc командой. C помощью утилиты `curl` проверим работу сервиса и загрузку данных из базы для всех нод:

```bash
ansible application -a "curl localhost:5000" -m shell
```

### Задание 3: Установить балансировщик нагрузки nginx используя ad-hoc команды

Поставим необходимый пакет nginx, давайте установим его без плейбука:

```bash
ansible ansible_master -a "name=nginx update_cache=yes cache_valid_time=3600 state=present" -m apt
```

Скопируем шаблон конфигурационного файла nginx, поставив в него хосты наших приложений, используется шаблизатор [jinja](https://jinja.palletsprojects.com/en/3.0.x/templates/):

```bash
ansible ansible_master -a "src=playbooks/nginx/nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root" -m template
```

и запустим `nginx` из консоли на хосте `ansible_ansible_1`:

```bash
nginx
```

Проверим работу nginx вызвав с нашей хост машины: [localhost:8080](localhost:8080).

:::caution
Если вы работаете на виртуальной машине, не забудьте выполнить проброс порта `8080`.
:::

### Задание 4: Добавить еще один экземпляр `ansible_app_4`

Добавить еще один экземпляр приложения `python`, прописав изменения во всех необходимых файлах.

## Контрольные вопросы

- Что в ходит в состав ansible playbook?
- Что такое группы хостов?
- Как одной командой "пингануть" группу хостов?
